package scales.xml.xpath
import scales.xml._
import scales.utils._
trait SiblingsAxis extends Axis {
def preceding_sibling_:: : XPath[T] =
xflatMap {
_.filter { _.hasPreviousSibling }.
map {
path =>
val pos = path.node.index
path.zipUp.splitAt(pos)._1.toList.reverse
}
}
def following_sibling_:: : XPath[T] =
xflatMap {
_.filter { _.hasNextSibling }.
map {
path =>
val pos = path.node.index
path.zipUp.splitAt(pos)._2.drop(1)
}
}
}
trait AttributeAxis extends Axis {
def i_*@ : Iterable[AttributePath] =
path.nodes.flatMap {
_.flatMap { child =>
if (child.isItem == true) Nil
else child.tree.section.attributes.map { x =>
AttributePath(x, child);
}
}
}
import ScalesXml._
def *@ : AttributePaths[T] =
AttributePaths(i_*@, path, cbf)
def *@(pred : AttributePath => Boolean) : AttributePaths[T] =
AttributePaths(i_*@.filter { pred(_) }, path, cbf)
def *@(attrQName : AttributeQName) : AttributePaths[T] =
*@({ attributePath : AttributePath => toQName(attributePath.attribute.name) =:= toQName(attrQName) })
def *@(qname : UnprefixedQName) : AttributePaths[T] =
*@({ attributePath : AttributePath => toQName(attributePath.attribute.name) =:= qname })
def \@ = \.*@
def *:@(local : String) : AttributePaths[T] =
*@({ attributePath : AttributePath => toQName(attributePath.attribute.name).local == local })
def \*:@(local : String) = \.*:@(local)
def \@(pred : AttributePath => Boolean) : AttributePaths[T] =
\.*@(pred)
def \@(attrQName : AttributeQName) : AttributePaths[T] =
\.*@(attrQName)
def \@(qname : UnprefixedQName) : AttributePaths[T] =
\.*@(qname)
def \\@ = \\.*@
def \\@(pred : AttributePath => Boolean) : AttributePaths[T] =
\\.*@(pred)
def \\@(attrQName : AttributeQName) : AttributePaths[T] =
\\.*@(attrQName)
def \\@(qname : UnprefixedQName) : AttributePaths[T] =
\\.*@(qname)
}
trait ElementStep extends Axis {
private[this] def \*- : XPath[T] =
xflatMap(_.filter { isElem })
def *(qname : QName) : XPath[T] = filter(x => x.isItem == false && qname =:= x.tree.section.name)
def \*(qname : QName) : XPath[T] =
\*-.*(qname)
def *:*(local : String) : XPath[T] = filter(x => x.isItem == false && local == x.tree.section.name.local)
def \*:*(local : String) : XPath[T] =
\*-.*:*(local)
def *(pred : XmlPath => Boolean) : XPath[T] = filter(x => x.isItem == false && pred(x))
def \*(pred : XmlPath => Boolean) : XPath[T] = \*-.*(pred)
def *(pos : Int) : XPath[T] =
xflatMap { path =>
val n = path.filter(_.isItem == false).take(pos)
if (n.size != pos) empty
else one(just(n.last))
}
def \*(pos : Int) : XPath[T] = \*-.*(pos)
def * : XPath[T] =
filter(isElem)
def \* : XPath[T] = \*-.*
def \\* : XPath[T] = \\.*
def \\*(qname : QName) = \\.*(qname)
def \\*:*(local : String) = \\.*:*(local)
def \\*(pred : XmlPath => Boolean ) = \\.*(pred)
def \\*(pos : Int) = \\.*(pos)
}
trait OtherNodeTypes extends Axis {
def textOnly : XPath[T] =
filter(x => x.isItem == true && x.item().isInstanceOf[Text])
def text : XPath[T] =
filter(isText)
def cdata : XPath[T] =
filter(x => x.isItem == true && x.item().isInstanceOf[CData])
def : XPath[T] =
filter( => x.isItem == true && x.item().isInstanceOf[Comment])
def pi : XPath[T] =
filter(x => x.isItem == true && x.item().isInstanceOf[PI])
}
trait DocumentSplitters extends Axis {
import Axis._
def descendant_:: : XPath[T] = {
val f = lazy_recUnpack(this) _
process(path.nodes.map { f }, path.copy(direct = true))
}
def following_:: : XPath[T] =
xflatMap { _.map{
new Following( _ )
} }
def preceding_:: : XPath[T] =
xflatMap { _.map{
new Preceding( _ )
} }
def ancestor_:: : XPath[T] =
xflatMap { _.map{
new Ancestors( _ )
} }
def ancestor_or_self_:: : XPath[T] =
xflatMap { _.map{ x =>
new Ancestors( x ) ++ one(x)
} }
def descendant_or_self_:: : XPath[T] = {
val f = lazy_recUnpack(this) _
process(path.nodes.map { x => f(x) ++ x },
path.copy(direct = true))
}
}